home *** CD-ROM | disk | FTP | other *** search
/ MIDICraft's MIDINET CD-ROM / MIDICraft's MIDINET CD-ROM.iso / DOSUTILS / KORG / SENDI3.CPP < prev    next >
C/C++ Source or Header  |  1996-11-30  |  14KB  |  660 lines

  1. // sendi3: (c) Günter Nagler 1996
  2. #include <stdio.h>
  3. #include <conio.h>
  4. #include <string.h>
  5. #include "sb.hpp"
  6. #include "korg.hpp"
  7. #include "filei3.hpp"
  8. #include <dir.h>
  9.  
  10. Soundcard* card = 0;
  11.  
  12. char* inputname = 0;
  13. unsigned char data[5000];
  14. int len = 0;
  15. int aborted = 0;
  16.  
  17. // convert into 7 bit data and send
  18. int senddumpdata(Soundcard* card, FILE* f, long pos, long len)
  19. {
  20.   if (!f || len <= 0 || !card)
  21.      return 0;
  22.  
  23.   fseek(f, pos, SEEK_SET);
  24.   if (ftell(f) != pos)
  25.     return 0;
  26.  
  27.   unsigned char data8[7];
  28.   int datalen = 0;
  29.   long sum = 0;
  30.   fprintf(stderr, "0%%  \r");
  31.   while (sum < len)
  32.   {
  33.     if (kbhit() && getch() == 27)
  34.     {
  35.       fprintf(stderr, "send aborted\n");
  36.       aborted = 1;
  37.       data[0] = 0xf7;
  38.       if (!card->play(data, 1))
  39.     fprintf(stderr, "error: data byte %02X not sent\n");
  40.       return 0;
  41.     }
  42.     if (datalen + 8 > sizeof(data))
  43.     {
  44.       if (card->play(data, datalen) != datalen)
  45.       {
  46.     fprintf(stderr, "error while sending data\n");
  47.     break;
  48.       }
  49.       fprintf(stderr, "%d%%  \r", (int)((sum * 100)/len));
  50.       datalen = 0;
  51.     }
  52.     int n = fread(data8, 1, 7, f);
  53.     if (n <= 0)
  54.       break;
  55.     sum += n;
  56.     n = code7to8(data8, n, data+datalen);
  57.     datalen += n;
  58.   }
  59.   card->play(data, datalen);
  60.   fprintf(stderr, "100%%\r");
  61.   return len == sum;
  62. }
  63.  
  64. int sendpcgdump(char* pcgfilename)
  65. {
  66.   FILE* f = fopen(pcgfilename, "rb");
  67.   if (!f)
  68.     return 0;
  69.  
  70.   data[0] = 0xf0;
  71.   data[1] = 0x42;
  72.   data[2] = 0x30;
  73.   data[3] = 0x39;
  74.   data[4] = 0x4c;
  75.  
  76.   rewind(f);
  77.   PCGHEAD head;
  78.  
  79.   if (fread(&head, sizeof(head), 1, f) != 1 || strncmp(head.korg, "KORG", 4) != 0 || head.b1.adr != 0x58)
  80.   {
  81.     fprintf(stderr, "this is not a KORG PCG file (or a bad one)\n");
  82.     return 0;
  83.   }
  84.   printf("sending %s to KORG ...\n", inputname);
  85.   card->play(data, 5);
  86.   if (!senddumpdata(card, f, head.progdata.adr, head.progdata.len))
  87.   {
  88.     if (!aborted)
  89.       fprintf(stderr, "read error or file too short\n");
  90.     return 0;
  91.   }
  92.   data[0] = 0xf7; // eox
  93.   card->play(data, 1);
  94.   fclose(f);
  95.   return 1;
  96. }
  97.  
  98. int sendstydump(char* styfilename)
  99. {
  100.   FILE* f = fopen(styfilename, "rb");
  101.   if (!f)
  102.     return 0;
  103.  
  104.   data[0] = 0xf0;
  105.   data[1] = 0x42;
  106.   data[2] = 0x30;
  107.   data[3] = 0x39;
  108.   data[4] = 0x65;
  109.  
  110.   rewind(f);
  111.   STYHEAD head;
  112.  
  113.   if (fread(&head, sizeof(head), 1, f) != 1 || strncmp(head.korg, "KORG", 4) != 0 || head.stylenames.adr != 0x20)
  114.   {
  115.     fprintf(stderr, "this is not a KORG STY file (or a bad one)\n");
  116.     return 0;
  117.   }
  118.  
  119.   fseek(f, 0, SEEK_END);
  120.   long flen = ftell(f);
  121.  
  122.   printf("sending %s to KORG ...\n", inputname);
  123.   card->play(data, 5);
  124.  
  125.   long datapos = head.styletable.adr;
  126.   if (!senddumpdata(card, f, datapos, flen-datapos))
  127.   {
  128.     if (!aborted)
  129.       fprintf(stderr, "read error or file too short\n");
  130.     return 0;
  131.   }
  132.   data[0] = 0xf7;
  133.   card->play(data, 1);
  134.  
  135.   fclose(f);
  136.   return 1;
  137. }
  138.  
  139. int sendarrdump(char* arrfilename)
  140. {
  141.   FILE* f = fopen(arrfilename, "rb");
  142.   if (!f)
  143.     return 0;
  144.  
  145.   data[0] = 0xf0;
  146.   data[1] = 0x42;
  147.   data[2] = 0x30;
  148.   data[3] = 0x39;
  149.   data[4] = 0x64;
  150.  
  151.   rewind(f);
  152.   ARRHEAD head;
  153.  
  154.   if (fread(&head, sizeof(head), 1, f) != 1 || strncmp(head.korg, "KORG", 4) != 0 || head.arrnames.adr != 0x20)
  155.   {
  156.     fprintf(stderr, "this is not a KORG ARR file (or a bad one)\n");
  157.     return 0;
  158.   }
  159.  
  160.   printf("sending %s to KORG ...\n", inputname);
  161.   card->play(data, 5);
  162.  
  163.   if (!senddumpdata(card, f, head.arrdata.adr, head.arrdata.len))
  164.   {
  165.     if (!aborted)
  166.       fprintf(stderr, "read error or file too short\n");
  167.     return 0;
  168.   }
  169.   data[0] = 0xf7;
  170.   card->play(data, 1);
  171.  
  172.   fclose(f);
  173.   return 1;
  174. }
  175.  
  176. int sendbsqdump(char* bsqfilename)
  177. {
  178.   FILE* f = fopen(bsqfilename, "rb");
  179.   if (!f)
  180.     return 0;
  181.  
  182.   data[0] = 0xf0;
  183.   data[1] = 0x42;
  184.   data[2] = 0x30;
  185.   data[3] = 0x39;
  186.   data[4] = 0x66;
  187.  
  188.   rewind(f);
  189.   BSQHEAD head;
  190.  
  191.   if (fread(&head, sizeof(head), 1, f) != 1 || strncmp(head.korg, "KORG", 4) != 0)
  192.   {
  193.     fprintf(stderr, "this is not a KORG BSQ file (or a bad one)\n");
  194.     return 0;
  195.   }
  196.  
  197.   fseek(f, 0, SEEK_END);
  198.   long flen = ftell(f);
  199.  
  200.   long steps = (flen - 2308) >> 4;
  201.   if (steps == 0)
  202.      printf("%s is empty backing sequence\n", inputname);
  203.  
  204.   data[5] = (steps & 0x7f);
  205.   data[6] = (steps >> 7);
  206.  
  207.   printf("sending %s to KORG ...\n", inputname);
  208.   card->play(data, 7);
  209.  
  210.   long datapos = 0x10;
  211.   if (!senddumpdata(card, f, datapos, flen-datapos))
  212.   {
  213.     if (!aborted)
  214.       fprintf(stderr, "read error or file too short\n");
  215.     return 0;
  216.   }
  217.   data[0] = 0xf7;
  218.   card->play(data, 1);
  219.  
  220.   fclose(f);
  221.   return 1;
  222. }
  223.  
  224. int sendsngdump(char* sngfilename)
  225. {
  226.   FILE* f = fopen(sngfilename, "rb");
  227.   if (!f)
  228.     return 0;
  229.  
  230.   data[0] = 0xf0;
  231.   data[1] = 0x42;
  232.   data[2] = 0x30;
  233.   data[3] = 0x39;
  234.   data[4] = 0x48;
  235.  
  236.   rewind(f);
  237.   SNGHEAD head;
  238.  
  239.   if (fread(&head, sizeof(head), 1, f) != 1 || strncmp(head.korg, "KORG", 4) != 0)
  240.   {
  241.     fprintf(stderr, "this is not a KORG SNG file (or a bad one)\n");
  242.     return 0;
  243.   }
  244.  
  245.   fseek(f, 0, SEEK_END);
  246.   long flen = ftell(f);
  247.  
  248.   long steps = (flen - 3718) >> 4;
  249.   if (steps == 0)
  250.      printf("%s is empty song\n", inputname);
  251.  
  252.   data[5] = (steps & 0x7f);
  253.   data[6] = (steps >> 7);
  254.  
  255.   printf("sending %s to KORG ...\n", inputname);
  256.   card->play(data, 7);
  257.  
  258.   long datapos = 0x10;
  259.   if (!senddumpdata(card, f, datapos, flen-datapos))
  260.   {
  261.     if (!aborted)
  262.       fprintf(stderr, "read error or file too short\n");
  263.     return 0;
  264.   }
  265.   data[0] = 0xf7;
  266.   card->play(data, 1);
  267.  
  268.   fclose(f);
  269.   return 1;
  270. }
  271.  
  272. int sendglbdump(char* glbfilename)
  273. {
  274.   FILE* f = fopen(glbfilename, "rb");
  275.   if (!f)
  276.     return 0;
  277.  
  278.   data[0] = 0xf0;
  279.   data[1] = 0x42;
  280.   data[2] = 0x30;
  281.   data[3] = 0x39;
  282.   data[4] = 0x51;
  283.  
  284.   rewind(f);
  285.  
  286.   fseek(f, 0, SEEK_END);
  287.   long flen = ftell(f);
  288.   if (flen != 28)
  289.   {
  290.     fprintf(stderr, "this is not a KORG GLB file (or a bad one)\n");
  291.     return 0;
  292.   }
  293.  
  294.   printf("sending %s to KORG ...\n", inputname);
  295.   card->play(data, 5);
  296.  
  297.   if (!senddumpdata(card, f, 0, flen))
  298.   {
  299.     if (!aborted)
  300.       fprintf(stderr, "read error or file too short\n");
  301.     return 0;
  302.   }
  303.   data[0] = 0xf7;
  304.   card->play(data, 1);
  305.   fclose(f);
  306.   return 1;
  307. }
  308.  
  309. int senddktdump(char* dktfilename)
  310. {
  311.   FILE* f = fopen(dktfilename, "rb");
  312.   if (!f)
  313.     return 0;
  314.  
  315.   data[0] = 0xf0;
  316.   data[1] = 0x42;
  317.   data[2] = 0x30;
  318.   data[3] = 0x39;
  319.   data[4] = 0x52;
  320.  
  321.   rewind(f);
  322.  
  323.   fseek(f, 0, SEEK_END);
  324.   long flen = ftell(f);
  325.   if (flen != 840)
  326.   {
  327.     fprintf(stderr, "this is not a KORG DKT file (or a bad one)\n");
  328.     return 0;
  329.   }
  330.  
  331.   printf("sending %s to KORG ...\n", inputname);
  332.   card->play(data, 5);
  333.  
  334.   if (!senddumpdata(card, f, 0, flen))
  335.   {
  336.     if (!aborted)
  337.       fprintf(stderr, "read error or file too short\n");
  338.     return 0;
  339.   }
  340.   data[0] = 0xf7;
  341.   card->play(data, 1);
  342.   fclose(f);
  343.   return 1;
  344. }
  345.  
  346. void checkresponse()
  347. {
  348. #define RETRY   100
  349.  
  350.   card->startinput();
  351.  
  352.   for (long i = 0; i < RETRY; i++)
  353.   if (card->hear(data, 1))
  354.      break;
  355.   if (i == RETRY)
  356.     fprintf(stderr, "Warning: no response from KORG. Transfer might not work.\n");
  357.   else
  358.     fprintf(stderr, "KORG responded\n");
  359.  
  360.   card->stopinput();
  361. }
  362.  
  363. char* getext(char* filename)
  364. {
  365.   char* ext = strrchr(filename, '.');
  366.   if (ext)
  367.     return ext+1;
  368.   return filename + strlen(filename);
  369. }
  370.  
  371. int senddump(char* filename)
  372. {
  373. int ret;
  374.  
  375.   inputname = filename;
  376.   char* ext = getext(filename);
  377.   if (!*ext)
  378.     return 0;
  379.   if (stricmp(ext, "pcg") == 0)
  380.   {
  381.     ret = sendpcgdump(filename);
  382.   }
  383.   else if (stricmp(ext, "sty") == 0)
  384.   {
  385.     ret = sendstydump(filename);
  386.   }
  387.   else if (stricmp(ext, "arr") == 0)
  388.   {
  389.     ret = sendarrdump(filename);
  390.   }
  391.   else if (stricmp(ext, "bsq") == 0)
  392.   {
  393.     ret = sendbsqdump(filename);
  394.   }
  395.   else if (stricmp(ext, "sng") == 0)
  396.   {
  397.     ret = sendsngdump(filename);
  398.   }
  399.   else if (stricmp(ext, "glb") == 0)
  400.   {
  401.     ret = sendglbdump(filename);
  402.   }
  403.   else if (stricmp(ext, "dkt") == 0)
  404.   {
  405.     ret = senddktdump(filename);
  406.   }
  407.   else
  408.   {
  409.     fprintf(stderr, "%s: cannot handle this file\n", filename);
  410.     return 0;
  411.   }
  412.   if (!ret)
  413.      return ret;
  414.   // check if korg answers
  415.   card->startinput();
  416.   unsigned char c;
  417.   for (int i = 0; i < 1000; i++)
  418.     if (card->hear(&c, 1) && c == 0xf0)
  419.       break;
  420.  
  421.   if (c == 0xf0)
  422.   {
  423.      printf("korg answered: ");
  424.      int len = 0;
  425.      data[len++] = c;
  426.      while (len < sizeof(data) && card->hear(&c, 1) && c != 0xf7 && (kbhit() == 0 || getch() != 27))
  427.        data[len++] = c;
  428.      if (c == 0xf7)
  429.        data[len++] = c;
  430.  
  431.      if (data[4] == 0x26)
  432.        printf("data format error\n");
  433.      else if (data[4] == 0x23)
  434.        printf("data load completed\n");
  435.      else
  436.      {
  437.        for (int i = 0; i < len; i++)
  438.      printf(" %02X", data[i]);
  439.        printf("\nsee korg manual for meaning of this system exclusive message\n");
  440.      }
  441.   }
  442.   else
  443.     fprintf(stderr, "no answer from korg\n");
  444.   card->stopinput();
  445.   return ret;
  446. }
  447.  
  448. int iskorgext(char* ext)
  449. {
  450.   if (stricmp(ext, "pcg") == 0)
  451.     return 1;
  452.   if (stricmp(ext, "sty") == 0)
  453.     return 1;
  454.   if (stricmp(ext, "arr") == 0)
  455.     return 1;
  456.   if (stricmp(ext, "bsq") == 0)
  457.     return 1;
  458.   if (stricmp(ext, "sng") == 0)
  459.     return 1;
  460.   return 0;
  461. }
  462.  
  463. char glbfilename[128] = "";
  464. char dktfilename[128] = "";
  465. char pcgfilename[128] = "";
  466. char styfilename[128] = "";
  467. char arrfilename[128] = "";
  468. char sngfilename[128] = "";
  469. char bsqfilename[128] = "";
  470.  
  471. int main(int argc, char** argv)
  472. {
  473.   argc--; argv++;
  474.   while (argc > 0 && **argv == '-')
  475.   {
  476.     fprintf(stderr, "invalid option %s\n", *argv);
  477.     argc--; argv++;
  478.   }
  479.   if (argc == 0)
  480.   {
  481.      printf("usage: sendi3 filename ...\n");
  482.      printf("files are korg i3 files (pcg, sty, arr, bsq, sng) or glb, drk\n");
  483.      printf("pcg\tkorg i3 programs\n");
  484.      printf("sty\tkorg i3 styles\n");
  485.      printf("arr\tkorg i3 arrangements\n");
  486.      printf("bsq\tkorg i3 backing sequences\n");
  487.      printf("sng\tkorg i3 songs\n");
  488.      printf("glb\tkorg i3 global settings\n");
  489.      printf("drk\tkorg i3 drumkit parameters\n");
  490.      printf("dos wildcards (*, ?) can be used\n");
  491.      return 1;
  492.   }
  493.   char* ext = getext(inputname);
  494.   if (!*ext)
  495.   {
  496.     fprintf(stderr, "filename %s has no extension\n", inputname);
  497.     return 0;
  498.   }
  499.  
  500.   int ret = 0;
  501.   struct ffblk ff;
  502.   char fullname[128];
  503.  
  504.   while (argc > 0 && **argv != '-')
  505.   {
  506.     char* filename = *argv++; argc--;
  507.  
  508.     strcpy(fullname, filename);
  509.     inputname = fullname;
  510.     char* name = strrchr(fullname, '\\');
  511.     if (name)
  512.       name++;
  513.     else
  514.     {
  515.       name = strchr(fullname, ':');
  516.       if (name)
  517.      name++;
  518.       else
  519.      name = fullname;
  520.     }
  521.     int done = findfirst(fullname, & ff, 0);
  522.     if (done)
  523.     {
  524.        fprintf(stderr, "%s: no files found\n", inputname);
  525.        return 1;
  526.     }
  527.     while (done == 0)
  528.     {
  529.       strcpy(name, ff.ff_name);
  530.       strupr(fullname);
  531.  
  532.       char* ext = getext(fullname);
  533.       if (strcmp(ext, "GLB") == 0)
  534.       {
  535.     if (*glbfilename != 0 && strcmp(fullname, glbfilename) != 0)
  536.     {
  537.       fprintf(stderr, "cannot send more than one global data (%s,%s)\n", fullname, glbfilename);
  538.       return 1;
  539.     }
  540.     strcpy(glbfilename, fullname);
  541.       }
  542.       else if (strcmp(ext, "DKT") == 0)
  543.       {
  544.     if (*dktfilename != 0 && strcmp(fullname, dktfilename) != 0)
  545.     {
  546.       fprintf(stderr, "cannot send more than one drumkit data (%s,%s)\n", fullname, dktfilename);
  547.       return 1;
  548.     }
  549.     strcpy(dktfilename, fullname);
  550.       }
  551.       else if (strcmp(ext, "PCG") == 0)
  552.       {
  553.     if (*pcgfilename != 0 && strcmp(fullname, pcgfilename) != 0)
  554.     {
  555.       fprintf(stderr, "cannot send more than one program data file (%s,%s)\n", fullname, pcgfilename);
  556.       return 1;
  557.     }
  558.     strcpy(pcgfilename, fullname);
  559.       }
  560.       else if (strcmp(ext, "STY") == 0)
  561.       {
  562.     if (*styfilename != 0 && strcmp(fullname, styfilename) != 0)
  563.     {
  564.       fprintf(stderr, "cannot send more than one style data file (%s,%s)\n", fullname, styfilename);
  565.       return 1;
  566.     }
  567.     strcpy(styfilename, fullname);
  568.       }
  569.       else if (strcmp(ext, "ARR") == 0)
  570.       {
  571.     if (*arrfilename != 0 && strcmp(fullname, arrfilename) != 0)
  572.     {
  573.       fprintf(stderr, "cannot send more than one arrangement data file (%s,%s)\n", fullname, arrfilename);
  574.       return 1;
  575.     }
  576.     strcpy(arrfilename, fullname);
  577.       }
  578.       else if (strcmp(ext, "BSQ") == 0)
  579.       {
  580.     if (*bsqfilename != 0 && strcmp(fullname, bsqfilename) != 0)
  581.     {
  582.       fprintf(stderr, "cannot send more than one backing sequence data file (%s,%s)\n", fullname, bsqfilename);
  583.       return 1;
  584.     }
  585.     strcpy(bsqfilename, fullname);
  586.       }
  587.       else if (strcmp(ext, "SNG") == 0)
  588.       {
  589.     if (*sngfilename != 0 && strcmp(fullname, sngfilename) != 0)
  590.     {
  591.       fprintf(stderr, "cannot send more than one song data file (%s,%s)\n", fullname, sngfilename);
  592.       return 1;
  593.     }
  594.     strcpy(sngfilename, fullname);
  595.       }
  596.       else
  597.     fprintf(stderr, "file %s ignored\n", fullname);
  598.  
  599.       if (aborted)
  600.     break;
  601.       done = findnext(&ff);
  602.     }
  603.   }
  604.  
  605.   card = detect_soundcard();
  606.   if (!card)
  607.   {
  608.     fprintf(stderr, "Could not detect soundcard\n");
  609.     return 1;
  610.   }
  611.  
  612.   checkresponse();
  613.  
  614.   if (*glbfilename)
  615.   {
  616.      int r = senddump(glbfilename);
  617.      if (r)
  618.        ret = r;
  619.   }
  620.   if (*dktfilename)
  621.   {
  622.      int r = senddump(dktfilename);
  623.      if (r)
  624.        ret = r;
  625.   }
  626.   if (*pcgfilename)
  627.   {
  628.      int r = senddump(pcgfilename);
  629.      if (r)
  630.        ret = r;
  631.   }
  632.   if (*styfilename)
  633.   {
  634.      int r = senddump(styfilename);
  635.      if (r)
  636.        ret = r;
  637.   }
  638.   if (*arrfilename)
  639.   {
  640.      int r = senddump(arrfilename);
  641.      if (r)
  642.        ret = r;
  643.   }
  644.   if (*bsqfilename)
  645.   {
  646.      int r = senddump(bsqfilename);
  647.      if (r)
  648.        ret = r;
  649.   }
  650.   if (*sngfilename)
  651.   {
  652.      int r = senddump(sngfilename);
  653.      if (r)
  654.        ret = r;
  655.   }
  656.  
  657.   delete card;
  658.   return ret;
  659. }
  660.